package it.mp.multitask.factory;

import it.mp.multitask.Main;
import it.mp.multitask.R;
import it.mp.multitask.Setup;
import it.mp.multitask.bean.App;
import it.mp.multitask.utility.AppComparator;
import it.mp.multitask.utility.IconManager;
import it.mp.multitask.utility.PatternEntry;
import it.mp.multitask.utility.RecentTaskInfoComparator;
import it.mp.multitask.utility.RunningServiceInfoComparator;
import it.mp.multitask.utility.RunningTaskInfoComparator;
import it.mp.multitask.view.HorizontalScrollViewTask;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.StringTokenizer;
import android.app.ActivityManager;
import android.app.ActivityManager.RecentTaskInfo;
import android.app.ActivityManager.RunningServiceInfo;
import android.app.ActivityManager.RunningTaskInfo;
import android.content.SharedPreferences;
import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.drawable.BitmapDrawable;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.View.MeasureSpec;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.LinearLayout.LayoutParams;

public class StyleStandard implements Style {

	private SharedPreferences prefs;
	private BitmapDrawable bmpCestino = null;
	private Main main = null;
	private int dimensioneSchermo;
	private IconManager iconManager;

	public StyleStandard(SharedPreferences prefs, BitmapDrawable bmpCestino, Main main, int dimensioneSchermo) {
		this.prefs = prefs;
		this.bmpCestino = bmpCestino;
		this.main = main;
		this.dimensioneSchermo = dimensioneSchermo;
	}

	public void crea(int NUMERO_PROCESSI_RUNNING, int NUMERO_PROCESSI_RECENTLY, int NUMERO_PROCESSI_SERVICE, int margin, boolean alphabeticOrder) {
		main.setContentView(R.layout.main);
		main.gestureDetector = new GestureDetector(main, new SimpleOnGestureListener());
		main.gestureDetector.setOnDoubleTapListener(new MyGestureDetector(prefs.getBoolean(main.getResources().getString(R.string.app_double_click), false)));

		final int patternRunning = PatternEntry.decodePattern(prefs.getString(main.getResources().getString(R.string.pref_background_theme), PatternEntry
				.primoValore()), 0);
		final int patternService = PatternEntry.decodePattern(prefs.getString(main.getResources().getString(R.string.pref_background_theme_srv), PatternEntry
				.primoValore()), 0);
		final int patternRecently = PatternEntry.decodePattern(prefs.getString(main.getResources().getString(R.string.pref_background_theme_rc), PatternEntry
				.primoValore()), 0);
		final int patternPreferred = PatternEntry.decodePattern(prefs.getString(main.getResources().getString(R.string.pref_background_theme_pa), PatternEntry
				.primoValore()), 0);

		final LinearLayout llContent = (LinearLayout) main.findViewById(R.id.LL_contenitore);

		main.findViewById(R.id.LL_parent).setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				if (!prefs.getBoolean(main.getResources().getString(R.string.app_double_click), false)) {
					main.finish();
				}
			}
		});
		main.findViewById(R.id.LL_parent).setOnTouchListener(new OnTouchListener() {
			public boolean onTouch(View v, MotionEvent event) {
				return main.gestureDetector.onTouchEvent(event);
			}
		});

		final LinearLayout llPreferred = (LinearLayout) main.findViewById(R.id.LL_task_0);
		final LinearLayout llRecently = (LinearLayout) main.findViewById(R.id.LL_task_1);
		final LinearLayout llRunning = (LinearLayout) main.findViewById(R.id.LL_task_2);
		final LinearLayout llService = (LinearLayout) main.findViewById(R.id.LL_task_3);
		final String scrollByGroup = prefs.getString(main.getResources().getString(R.string.theme_mode), "1");
		final ActivityManager actvityManager = (ActivityManager) main.getSystemService(Main.ACTIVITY_SERVICE);

		final boolean showDeleted = prefs.getBoolean(main.getResources().getString(R.string.app_show_app_deleted_by_system), false);

		final HashSet<String> hs = new HashSet<String>();
		hs.add("it.mp.multitask##it.mp.multitask.Main");
		hs.add("com.android.phone##com.android.phone.InCallScreen");

		final boolean showRecycle = prefs.getBoolean(main.getResources().getString(R.string.app_recycle_bin), true);
		final boolean dontShowTitle = prefs.getBoolean(main.getResources().getString(R.string.app_show_title), false);
		final int iconSize = Integer.valueOf(prefs.getString(main.getResources().getString(R.string.app_title_size), "48")).intValue();

		iconManager = new IconManager(iconSize, bmpCestino);

		if (prefs.getBoolean(Main.PREF_APP_RUNNING, true)) {
			getAndShowRunningApps(NUMERO_PROCESSI_RUNNING, actvityManager, hs, llRunning, margin, alphabeticOrder, scrollByGroup, showRecycle, showDeleted,
					dontShowTitle, iconSize);
			BitmapDrawable bd = PatternEntry.createDrawable(main.getResources(), patternRunning, 0);
			if (bd == null) {
				llRunning.setBackgroundResource(patternRunning);
			} else {
				llRunning.setBackgroundDrawable(bd);
			}
		} else {
			llContent.removeView(llRunning);
			llContent.removeView(main.findViewById(R.id.LL_title_2));
		}
		if (prefs.getBoolean(Main.PREF_APP_RECENTLY, true)) {
			getAndShowRecentlyClosedApps(NUMERO_PROCESSI_RECENTLY, llRecently, actvityManager, hs, margin, alphabeticOrder,
					(patternRunning == patternRecently), scrollByGroup, dontShowTitle, iconSize);
			BitmapDrawable bd = PatternEntry.createDrawable(main.getResources(), patternRecently, 0);
			if (bd == null) {
				llRecently.setBackgroundResource(patternRecently);
			} else {
				llRecently.setBackgroundDrawable(bd);
			}
		} else {
			llContent.removeView(llPreferred);
			llContent.removeView(main.findViewById(R.id.LL_title_1));
		}

		int numPreferredApps = getAndShowPreferredApps(hs, llPreferred, margin, alphabeticOrder, (patternPreferred == patternRecently), scrollByGroup,
				dontShowTitle, iconSize);
		if (numPreferredApps == 0) {
			llContent.removeView(llPreferred);
			llContent.removeView(main.findViewById(R.id.LL_title_0));
		} else {
			BitmapDrawable bd = PatternEntry.createDrawable(main.getResources(), patternPreferred, 0);
			if (bd == null) {
				llPreferred.setBackgroundResource(patternPreferred);
			} else {
				llPreferred.setBackgroundDrawable(bd);
			}
		}

		if (prefs.getBoolean(Main.PREF_APP_SERVICE, false)) {
			getAndShowServiceApps(NUMERO_PROCESSI_SERVICE, llService, actvityManager, hs, margin, alphabeticOrder, (patternRunning == patternService),
					scrollByGroup, showRecycle, showDeleted, iconSize,dontShowTitle);
			BitmapDrawable bd = PatternEntry.createDrawable(main.getResources(), patternService, 0);
			if (bd == null) {
				llService.setBackgroundResource(patternService);
			} else {
				llService.setBackgroundDrawable(bd);
			}
		} else {
			llContent.removeView(llService);
			llContent.removeView(main.findViewById(R.id.LL_title_3));
		}

		setScroll(scrollByGroup);
		setGroupTitle(actvityManager);
	}

	private void getAndShowRunningApps(int numero, ActivityManager actvityManager, HashSet<String> hs, LinearLayout linearLayout, int margin,
			boolean alphabeticOrder, String firstGroup, boolean showRecycle, boolean showDeleted, boolean showTitle, int iconSize) {
		App app = null;
		int size;
		List<RunningTaskInfo> procInfos = actvityManager.getRunningTasks(numero);
		if (alphabeticOrder) {
			Collections.sort(procInfos, new RunningTaskInfoComparator(main.getPackageManager()));
		}
		size = procInfos.size();
		for (int i = 0; i < size; i++) {
			RunningTaskInfo rti = procInfos.get(i);
			if ((rti.numRunning == 0) && (!showDeleted)) {
			} else {
				try {
					app = new App(main, rti, showRecycle, iconManager);
				} catch (NameNotFoundException e1) {

				}
				if (app != null) {
					if (prefs.getBoolean(app.getPackageName(), false)) {

					} else {
						if (!hs.contains(app.toString())) {
							app.setOnClickListener(main.oclStartActivity);
							app.setOnLongClickListener(main.oclKillActivity);
							try {
								linearLayout.addView(app.getView(margin, bmpCestino, showTitle, iconSize), new LinearLayout.LayoutParams(linearLayout
										.getLayoutParams().width, linearLayout.getLayoutParams().height));
							} catch (NameNotFoundException e) {
							}
							hs.add(app.toString());
						}
					}
				}
			}
		}

		if ("1".equals(firstGroup)) {
			setBlankSpace(linearLayout);
		} else {
			if (size == 1) {
				setBlankSpaceForFillParent(linearLayout);
			}
		}

	}

	private void getAndShowRecentlyClosedApps(int numero, LinearLayout linearLayout, ActivityManager actvityManager, HashSet<String> hs, int margin,
			boolean alphabeticOrder, boolean impostaMargine, String firstGroup, boolean showTitle, int iconSize) {

		App app = null;
		int size;
		List<RecentTaskInfo> recInfos = actvityManager.getRecentTasks(numero + hs.size(), 0);
		if (alphabeticOrder) {
			Collections.sort(recInfos, new RecentTaskInfoComparator(main.getPackageManager()));
		}
		size = recInfos.size();
		int numeApps=0;
		for (int i = 0; i < size; i++) {
			try {
				app = new App(main, recInfos.get(i), iconManager);
			} catch (NameNotFoundException e) {

			}
			if (app != null) {
				if (prefs.getBoolean(app.getPackageName(), false)) {

				} else {
					if (!hs.contains(app.toString())) {
						try {
							app.setOnClickListener(main.oclStartActivity);
							linearLayout.addView(app.getView(margin, showTitle, iconSize), new LinearLayout.LayoutParams(linearLayout.getLayoutParams().width,
									linearLayout.getLayoutParams().height));
							hs.add(app.toString());
							numeApps++;
						} catch (NameNotFoundException nnfex) {

						}
					}
				}
			}
			if (numeApps==numero){
				break;
			}
		}
		if (impostaMargine) {
			linearLayout.addView(main.getLayoutInflater().inflate(R.layout.app_separatore, null));
		}
		if ("2".equals(firstGroup)) {
			setBlankSpace(linearLayout);
		} else {
			if (size == 1) {
				setBlankSpaceForFillParent(linearLayout);
			}
		}
	}

	private int getAndShowPreferredApps(HashSet<String> hs, LinearLayout linearLayout, int margin, boolean alphabeticOrder, boolean impostaMargine,
			String firstGroup, boolean showTitle, int iconSize) {
		int size = 0;
		String lista = prefs.getString(main.getResources().getString(R.string.Apps_list_preferred), ";");
		StringTokenizer st = new StringTokenizer(lista, ";");
		App app = null;
		String chiave;
		if (true) {
			ArrayList<App> alAppo = new ArrayList<App>();
			HashSet<String> hsTmp=new HashSet<String>();
			while (st.hasMoreTokens()) {
				chiave = st.nextToken();
				if (prefs.getBoolean(chiave, false)) {
					chiave = chiave.replace(Setup.PREFIX_PREFERRED_APPS, "");
					try {
						app = new App(main, chiave, iconManager);
					} catch (NameNotFoundException e) {

					}
					if (app != null) {
						if (!hsTmp.contains(app.toString())) {
							alAppo.add(app);
							size++;
							hsTmp.add(app.toString());
						}
					}
				}
			}
			if (alAppo.size() > 0) {
				hs.addAll(hsTmp);
				Collections.sort(alAppo, new AppComparator(main.getPackageManager()));
				for (int i = 0; i < alAppo.size(); i++) {
					try {
						alAppo.get(i).setOnClickListener(main.oclStartActivity);
						linearLayout.addView(alAppo.get(i).getView(margin, showTitle, iconSize), new LinearLayout.LayoutParams(
								linearLayout.getLayoutParams().width, linearLayout.getLayoutParams().height));
					} catch (NameNotFoundException e) {
					}
				}
			}
		} 

		if (impostaMargine) {
			linearLayout.addView(main.getLayoutInflater().inflate(R.layout.app_separatore, null));
		}
		if ((size > 0) && ("3".equals(firstGroup))) {
			setBlankSpace(linearLayout);
		} else {
			if (size == 1) {
				setBlankSpaceForFillParent(linearLayout);
			}
		}
		return size;
	}

	private void getAndShowServiceApps(int NUMERO_PROCESSI_SERVICE, LinearLayout linearLayout, ActivityManager actvityManager, HashSet<String> hs, int margin,
			boolean alphabeticOrder, boolean impostaMargine, String firstGroup, boolean showRecycle, boolean showDeleted, int iconSize,boolean showTitle) {
		if (impostaMargine) {
			linearLayout.addView(main.getLayoutInflater().inflate(R.layout.app_separatore, null));
		}

		App app;
		int size;
		List<RunningServiceInfo> recInfos = actvityManager.getRunningServices(NUMERO_PROCESSI_SERVICE);
		if (alphabeticOrder) {
			Collections.sort(recInfos, new RunningServiceInfoComparator(main.getPackageManager()));
		}
		size = recInfos.size();
		RunningServiceInfo rsi = null;
		for (int i = 0; i < size; i++) {
			rsi = recInfos.get(i);
			if ((!rsi.started) && (!showDeleted)) {
			} else {
				app = new App(main, rsi, showRecycle, iconManager);
				if (prefs.getBoolean(app.getPackageName(), false)) {

				} else {
					if (!hs.contains(app.toString())) {
						try {
							app.setOnClickListener(main.oclStartOptionPanel);
							app.setOnLongClickListener(main.oclKillActivity);
							linearLayout.addView(app.getView(margin, bmpCestino, true, showTitle, iconSize), new LinearLayout.LayoutParams(linearLayout
									.getLayoutParams().width, linearLayout.getLayoutParams().height));
							hs.add(app.toString());
						} catch (NameNotFoundException nnfex) {

						}
					}
				}
			}
		}
		if ("4".equals(firstGroup)) {
			setBlankSpace(linearLayout);
		}
	}

	private void setBlankSpace(ViewGroup linearLayout) {
		linearLayout.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.EXACTLY);
		int width = linearLayout.getMeasuredWidth();
		int diff = dimensioneSchermo - width;
		if (diff > 0) {
			LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
			lp.setMargins(diff, 0, 0, 0);
			ImageView v = new ImageView(main);
			v.setMinimumWidth(1);
			linearLayout.addView(v, -1, lp);
		} else {
			diff = 0;
		}
	}
	private void setBlankSpaceForFillParent(ViewGroup linearLayout) {
		ViewGroup parent = (ViewGroup) linearLayout.getParent();
		parent.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.EXACTLY);
		int widthParent = parent.getMeasuredWidth();
		int width = linearLayout.getMeasuredWidth();

		int diff = widthParent - width;
		if (diff > 0) {
			LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
			lp.setMargins(diff, 0, 0, 0);
			ImageView v = new ImageView(main);
			v.setMinimumWidth(1);
			linearLayout.addView(v, -1, lp);
		} else {
			diff = 0;
		}
	}
	private void setGroupTitle(ActivityManager actvityManager) {
		final boolean showTitle = prefs.getBoolean(main.getResources().getString(R.string.show_title), true);
		if (!showTitle) {
			if (main.findViewById(R.id.tv_title_0) != null) {
				main.findViewById(R.id.tv_title_0).setVisibility(View.INVISIBLE);
			}
			if (main.findViewById(R.id.tv_title_1) != null) {
				main.findViewById(R.id.tv_title_1).setVisibility(View.INVISIBLE);
			}
			if (main.findViewById(R.id.tv_title_2) != null) {
				main.findViewById(R.id.tv_title_2).setVisibility(View.INVISIBLE);
			}
			if (main.findViewById(R.id.tv_title_3) != null) {
				main.findViewById(R.id.tv_title_3).setVisibility(View.INVISIBLE);
			}
		} else {
			final boolean showavailableMemory = prefs.getBoolean(main.getResources().getString(R.string.app_show_available_memory), false);
			boolean killAll = prefs.getBoolean("pref_kill_all", false);
			if (showavailableMemory) {
				final ActivityManager.MemoryInfo mem = new ActivityManager.MemoryInfo();
				actvityManager.getMemoryInfo(mem);
				StringBuffer sb = new StringBuffer(" ");
				sb.append(main.getResources().getString(R.string.available));
				sb.append(": ");
				sb.append((int) mem.availMem / 1048576);
				sb.append(" Mb.");
				final TextView tv = ((TextView) main.findViewById(R.id.tv_title_2));
				if (tv != null) {
					tv.setText(tv.getText() + sb.toString());
				}
				if (killAll) {
					tv.setOnClickListener(this.main.oclKillAllActivity);
				}
			}
		}
	}
	private void setScroll(String scrollByGroup) {
		final HorizontalScrollViewTask hsv = (HorizontalScrollViewTask) main.findViewById(R.id.HSV_contenitore);
		if ("1".equals(scrollByGroup)) {
			int scrollWidth = 0;
			if (main.findViewById(R.id.LL_task_0) != null) {
				main.findViewById(R.id.LL_title_0).measure(MeasureSpec.UNSPECIFIED, MeasureSpec.EXACTLY);
				scrollWidth = main.findViewById(R.id.LL_task_0).getMeasuredWidth();
			}
			if (main.findViewById(R.id.LL_task_1) != null) {
				main.findViewById(R.id.LL_title_1).measure(MeasureSpec.UNSPECIFIED, MeasureSpec.EXACTLY);
				scrollWidth += main.findViewById(R.id.LL_task_1).getMeasuredWidth();
			}
			hsv.setScrollPosition(scrollWidth);
		} else if ("2".equals(scrollByGroup)) {
			int widthPreferred = 0;
			if (main.findViewById(R.id.LL_task_0) != null) {
				main.findViewById(R.id.LL_title_0).measure(MeasureSpec.UNSPECIFIED, MeasureSpec.EXACTLY);
				widthPreferred = main.findViewById(R.id.LL_task_0).getMeasuredWidth();
			}
			hsv.setScrollPosition(widthPreferred);
		} else if ("3".equals(scrollByGroup)) {
			hsv.setScrollPosition(0);
		} else if ("4".equals(scrollByGroup)) {
			int scrollWidth = 0;
			if (main.findViewById(R.id.LL_task_0) != null) {
				main.findViewById(R.id.LL_title_0).measure(MeasureSpec.UNSPECIFIED, MeasureSpec.EXACTLY);
				scrollWidth = main.findViewById(R.id.LL_task_0).getMeasuredWidth();
			}
			if (main.findViewById(R.id.LL_task_1) != null) {
				main.findViewById(R.id.LL_title_1).measure(MeasureSpec.UNSPECIFIED, MeasureSpec.EXACTLY);
				scrollWidth += main.findViewById(R.id.LL_task_1).getMeasuredWidth();
			}
			if (main.findViewById(R.id.LL_task_2) != null) {
				main.findViewById(R.id.LL_title_2).measure(MeasureSpec.UNSPECIFIED, MeasureSpec.EXACTLY);
				scrollWidth += main.findViewById(R.id.LL_task_2).getMeasuredWidth();
			}
			hsv.setScrollPosition(scrollWidth);
		}
	}

	public class MyGestureDetector implements GestureDetector.OnDoubleTapListener {
		boolean isDoppioClick = false;
		public MyGestureDetector(boolean valore) {
			super();
			isDoppioClick = valore;
		}

		public boolean onDoubleTap(MotionEvent e) {
			if (isDoppioClick) {
				main.finish();
				return true;
			} else {
				return false;
			}
		}

		public boolean onDoubleTapEvent(MotionEvent e) {
			if (isDoppioClick) {
				main.finish();
				return true;
			} else {
				return false;
			}
		}

		public boolean onSingleTapConfirmed(MotionEvent e) {
			return false;
		}

	}
}
